// 主要功能是避免错误多次重复打印，相同的错误只输出一次
package ee

// Error 自定义错误
type Error struct {
	msg string
	//where string
	count int
}

// NewError 新的错误
func NewError(msg string) *Error {
	if msg == "" {
		return nil
	}
	return newError(msg)
}

func newError(msg string) *Error {
	er := new(Error)
	// _, file, line, ok := runtime.Caller(2)
	// if !ok {
	// 	file = "???"
	// 	line = 0
	// }
	// _, filename := path.Split(file)
	// er.msg = "[" + filename + ":" + strconv.Itoa(line) + "] " + msg
	er.msg = msg
	return er
}

// New 构造一个错误
func New(err error) *Error {
	if err == nil {
		return nil
	}
	e, ok := err.(*Error)
	if ok && e != nil {
		return e
	}
	e = newError(err.Error())
	return e
}

// Error 实现 error 接口
func (m *Error) Error() string {
	return m.msg
}

// String ...
func (m *Error) String() string {
	m.count++
	return m.msg
}

// NeedToDisplay 是否需要错误
func (m *Error) NeedToDisplay() bool {
	return m.count == 0
}

// Data 纯消息
func (m *Error) Data() string {
	return m.msg
}

// Msg 纯消息 计数器会增长
func (m *Error) Msg() string {
	m.count++
	return m.msg
}

// Once1 只输出1次日志, 一个函数的回调
func (m *Error) Once1(f func(...interface{})) *Error {
	if m.count > 0 {
		return m
	}
	f(m.String())
	return m
}

// Once2 只输出1次日志
func (m *Error) Once2(f func(string, ...interface{})) *Error {
	if m.count > 0 {
		return m
	}
	f(m.String())
	return m
}

/**
 * @description: 只打印一次日志
 * @param {*} interface
 * @return {*}
 */
func (m *Error) Print(f func(...interface{})) *Error {
	if m.count > 0 {
		return m
	}
	f(m.String())
	return m
}

/**
 * @description: 只打印一次日志
 * @param {*} string
 * @param {*} interface
 * @return {*}
 */
func (m *Error) Printf(f func(string, ...interface{})) *Error {
	if m.count > 0 {
		return m
	}
	f(m.String())
	return m
}

/**
 * @description: 只打印一次日志
 * @param {*} interface
 * @return {*} 自动包装成 Error 类
 */
func Print(err error, f func(...interface{})) error {
	if err == nil {
		return nil
	}
	e, ok := err.(*Error)
	if ok && e != nil {
		if e.count > 0 {
			return err
		}
	} else {
		e = NewError(err.Error())
	}
	f(e.String())
	return e
}

/**
 * @description: 只打印一次日志
 * @param {*} interface
 * @return {*} 自动包装成 Error 类
 */
func PrintMsg(msg string, err error, f func(...interface{})) error {
	if err == nil {
		return nil
	}
	e, ok := err.(*Error)
	if ok && e != nil {
		if e.count > 0 {
			return err
		}
	} else {
		e = NewError(err.Error())
	}
	f(msg, e.String())
	return e
}

/**
 * @description: 只打印一次日志
 * @param {*} string
 * @param {*} interface
 * @return {*} 自动包装成 Error 类
 */
func Printf(err error, f func(string, ...interface{})) error {
	if err == nil {
		return nil
	}
	e, ok := err.(*Error)
	if ok && e != nil {
		if e.count > 0 {
			return err
		}
	} else {
		e = NewError(err.Error())
	}
	f(e.String())
	return e
}
